#ifndef TREE
#define TREE
#include <stdio.h>
// variable
#define null 0x0

const int PRIOR[3] = {1, 2, 3};

enum nodeType
{
    N_QUANT,
    N_PRID,
    N_CONJ,
    N_RAWNEG, //否定
    N_UNDEF
};

class variable
{ //变量类
public:
    char _v;
    variable *_next_v;
    variable() : _v('\0'), _next_v(null){};
    variable(char var)
    {
        this->_v = var;
        this->_next_v = null;
    }
};

typedef variable *vlist;

char get_var(vlist var)
{
    if (var != null)
    {
        return var->_v;
    }
}

vlist new_vars(char *array)
{ //根据形如“xyz”的字符数组产生一个参数列表
    vlist v = null;
    vlist head = null;
    if (array != null && *array != '\0')
    {
        head = new variable(*array);
        v = head;
        array++;
    }
    while (array != null && *array != '\0')
    {
        printf("%c", *array);
        // 调用变量类的构造函数
        v->_next_v = new variable(*array);
        v = v->_next_v;
        array++;
    }
    return head;
}

//  动态操作占主导
// 采用树形结构
class node
{ // 语法树当中的节点
    // 可能是运算符，量词，谓词或者变量
public:
    node *parent; //父节点
    node *_lc;    //左孩子
    node *_rc;    //右孩子

    nodeType _type; //节点的种类
    bool _neg;      //是否否定
    char _sym;      //节点符号
    variable *_vars; //节点的参数列表

    // 不同类型的构造函数
    static node *qunt(char q, char var);
    static node *prid(bool neg, char name, char *vars_string);
    static node *conj(char cj);
    static node *rawneg();

    node *ascend(); //返回当前节点的父节点，没有则创建一个

    node *descend_lc() { this->descend(true); };  //到达当前节点的左孩子
    node *descend_rc() { this->descend(false); }; //到达当前节点的右孩子
    node *descend(bool left);                     //一个节点

    void turn_positive();

    //以下三个是进行节点类型转换的函数
    node *to_quant(char q, char var);
    node *to_prid(bool neg, char name, char *vars_string);
    node *to_conj(char cj);

    node() : _type(N_UNDEF), _sym('\0'), _neg(false), _vars(null),parent(null),_lc(null),_rc(null){};
    ~node();

private:
    node(int type, bool neg, char sym, vlist vars);
};

node::node(int type, bool neg, char sym, vlist vars)
{
    this->_type = (nodeType)type;
    this->_neg = neg;
    this->_sym = sym;
    this->_vars = vars;
    this->parent = null;
    this->_lc = null;
    this->_rc = null;
}

node *node::qunt(char q, char var)
{
    return new node(N_QUANT, false, q, new variable(var));
}
node *node::prid(bool neg, char name, char *vars_string)
{
    return new node(N_PRID, false, name, new_vars(vars_string));
}
node *node::conj(char cj)
{
    return new node(N_CONJ, false, cj, null);
}
node *node::rawneg()
{
    return new node(N_RAWNEG, true, '\0', null);
}
node::~node()
{
    printf("析构节点：%c", this->_sym);
}

node *node::ascend()
{ //转到当前节点的父节点(or rather, higher level, not neccessarily direct parent node)
    // 临时节点
    node *temp = this;
    if (temp->parent != null)
    { // 存在父节点
        // 转向父节点

        temp = this->parent;
        // 由于写法限制，这里有两个特殊的返回规则
        // 判断是否需要继续上溯（特殊情况）
        if (temp->_type == N_RAWNEG)
        { //对于最开始产生的否定符号
            // 默认写法当中不带括号
            while (temp->parent->_type == N_RAWNEG)
            { //如果之前还有否定符号
                temp = temp->parent;
            }
            // 跳出了否定符号
            return temp->parent;
        }
        if (temp->_type == N_QUANT)
        { //当前节点的父节点是量词
            //和否定雷同
            if (temp->_type == N_RAWNEG)
            {
                // 默认写法当中不带括号
                while (temp->parent->_type == N_QUANT)
                { //如果之前还有量词
                    // 再上一层
                    temp = temp->parent;
                }
                // 直至跳出量词
                // 返回量词之上的节点
                return temp->parent;
            }
            return this->parent;
        }
    }
    else
    { //对于谓词，连接词，都没有这样的问题

        //创建父节点
        node *parent = new node();
        // 默认当前节点是左孩子
        parent->_lc = this;
        this->parent = parent;
        return parent;
    }
}

node *node::descend(bool left)
{
    if (left == true)
    {
        if (this->_lc != null)
        {
            return this->_lc;
        }
        else
        {
            node *lc = new node();
            // 注册父节点
            lc->parent = this;
            this->_lc = lc;
            return lc;
        }
    }
    else
    {
        if (this->_rc != null)
        {
            return this->_rc;
        }
        else
        {
            node *rc = new node();
            // 注册父节点
            rc->parent = this;
            this->_rc = rc;
            return rc;
        }
    }
}

node *node::to_conj(char c)
{
    if (this->_type == N_UNDEF)
    {
        this->_type = N_CONJ;
        this->_vars = null;
        this->_sym = c;
        this->_neg = false;
        return this;
    }
    else
    {
        return null; //返回空值供上层处理
    }
}

node *node::to_quant(char q, char var)
{
    if (this->_type == N_UNDEF)
    {
        this->_type = N_QUANT;
        this->_vars = new variable(var);
        this->_sym = q;
        this->_neg = false;
        return this;
    }
    else
    {
        return null; //返回空值供上层处理
    }
}
node *node::to_prid(bool neg, char name, char *vars_string)
{
    if (this->_type == N_UNDEF)
    { //未定义
        this->_type = N_PRID;
        this->_vars = new_vars(vars_string);
        this->_sym = name;
        this->_neg = neg;
        return this;
    }
    else
    {
        return null; //返回空值供上层处理
    }
}

void node::turn_positive()
{ //对于谓词之外的节点
    //利用_neg改变属性
    // 并且使_neg = ture
    //TODO
}
#endif